
import { 
  AmbientLight,
  ArrowHelper,
  BoxGeometry,
  Mesh,
  MeshBasicMaterial,
  MeshPhongMaterial,
  MeshNormalMaterial,
  PCFShadowMap,
  PerspectiveCamera,
  PlaneGeometry,
  Scene, 
  SphereGeometry, 
  SpotLight, 
  SpotLightHelper, 
  Vector3,
  WebGLRenderer,
  MeshLambertMaterial
} from 'three'
import stats from '../utils/stats'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'
import dat from 'dat.gui'

const scene = new Scene()
const camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000)
camera.position.set(-50, 75, 100)
camera.lookAt(new Vector3(10, 0, 0))

const renderer = new WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setClearColor(0x000000)
renderer.shadowMap.enabled = true
renderer.shadowMap.type = PCFShadowMap
document.body.appendChild(renderer.domElement)

const groundGeom = new PlaneGeometry(100, 100, 4, 4)
const groundMesh = new Mesh(groundGeom, new MeshPhongMaterial({
  color: 0x555555
}))
groundMesh.rotation.x = -Math.PI / 2
groundMesh.position.y = -20
groundMesh.receiveShadow = true
scene.add(groundMesh)

const sphereGeometry = new SphereGeometry(14, 20, 20)
const cubeGeometry = new BoxGeometry(15, 15, 15)
const planeGeometry = new PlaneGeometry(14, 14, 4, 4)

const meshMaterial = new MeshLambertMaterial({
  color: 0x7777ff
})
const sphere = new Mesh(sphereGeometry, meshMaterial)
const cube = new Mesh(cubeGeometry, meshMaterial)
const plane = new Mesh(planeGeometry, meshMaterial)

sphere.position.set(0, 0, 0)
sphere.castShadow = true

cube.position.copy(sphere.position)
cube.castShadow = true

plane.position.copy(sphere.position)
scene.add(sphere)
let selectedMesh = sphere

const spotLight = new SpotLight(0xffffff)
spotLight.position.set(-40, 60, -10)
spotLight.castShadow = true
spotLight.shadow.mapSize.set(1024, 1024)
spotLight.angle = 0.4
scene.add(spotLight)
scene.add(new SpotLightHelper(spotLight))

const controls = new function() {
  this.rotationSpeed = 0.02
  this.bouncingSpeed = 0.03
  this.selectedMesh = 'sphere'
  this.color = meshMaterial.color.getStyle()
  this.cube = cube
  this.sphere = sphere
  this.plane = plane
}

const gui = new dat.GUI()
gui.add(controls, 'rotationSpeed', 0, 0.5)
gui.add(controls, 'selectedMesh', ['cube', 'sphere', 'plane']).onChange(e => {
  scene.remove(sphere)
  scene.remove(cube)
  scene.remove(plane)

  scene.add(controls[e])
  selectedMesh = controls[e]
})
gui.addColor(controls, 'color').onChange(e => {
  meshMaterial.color.setStyle(e)
})

const trackballControls = new TrackballControls(camera, renderer.domElement)

function render() {
  stats.update()
  trackballControls.update()

  selectedMesh.rotation.y += controls.rotationSpeed

  requestAnimationFrame(render)
  renderer.render(scene, camera)
}
render()